package com.pan.crawler.auto;

import com.pan.crawler.Directory;
import com.pan.crawler.auto.action.TurnPage;
import com.pan.download5.parse.entity.auto.impl.AutoDirectory;
import com.pan.download5.parse.entity.auto.impl.AutoItem;
import com.pan.download5.parse.entity.auto.impl.AutoTitle;
import com.pan.crawler.auto.utils.AutoValueTools;
import com.pan.entity.BookDirectory;
import com.pan.entity.Chapter;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;

import java.time.Duration;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;

public class AutoCrawlerDirectory implements Directory {

    private AutoTitle autoTitle;
    private AutoDirectory autoDirectory;


    public AutoCrawlerDirectory(AutoTitle autoTitle, AutoDirectory autoDirectory) {
        this.autoTitle = autoTitle;
        this.autoDirectory = autoDirectory;
    }

    @Override
    public BookDirectory get(String url) {
        EdgeDriver edgeDriver = new EdgeDriver();
        EdgeOptions edgeOptions = new EdgeOptions();
        edgeOptions.addArguments("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
        edgeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));

        edgeDriver.navigate().to(url);

        BookDirectory bookDirectory = new BookDirectory();


        String titleXpath = autoTitle.getXpath();
        WebElement titleElement = edgeDriver.findElement(By.xpath(titleXpath));
        String title = titleElement.getText();

        String titleRegex = autoTitle.getClearRegex();
        if (!titleRegex.isEmpty()){
            title = title.replaceAll(titleRegex,"");
        }
        bookDirectory.setBookName(title);
        List<Chapter> chapterList = new LinkedList<>();
        bookDirectory.setChapterList(chapterList);

        String directoryXpath = this.autoDirectory.getXpath();
        AutoItem autoItem = this.autoDirectory.getItem();
        String itemXpath = autoItem.getXpath();


        class GetTargetValue implements Function<WebElement, String>{
            boolean isAttr;
            String attrName;
            String clearRegex;

            GetTargetValue(String chapValue, String clearRegex){
                this.clearRegex = clearRegex;
                AutoValueTools.Value value;
                try {
                    value = AutoValueTools.INSTANCE.parse(chapValue);
                }catch (RuntimeException e){
                    throw new RuntimeException("Error ChapValue: "+chapValue);
                }
                this.isAttr = value.isAttr();
                this.attrName = value.getAttrName();
            }

            @Override
            public String apply(WebElement webElement) {
                String result;
                if (isAttr) {
                    result = webElement.getAttribute(attrName);
                }
                else {
                    result = webElement.getText();
                }
                if (clearRegex != null && !clearRegex.isEmpty()) {
                    result = result.replaceAll(this.clearRegex, "");
                }
                return result;
            }
        }

        String chapXpath = autoItem.getChap().getXpath();
        String chapValue = autoItem.getChap().getValue();
        String chapClearRegex = autoItem.getChap().getClearRegex();
        Function<WebElement, String> getChapName = new GetTargetValue(chapValue,chapClearRegex);

        String urlXpath = autoItem.getUrl().getXpath();
        String urlValue = autoItem.getUrl().getValue();
        String urlClearRegex = autoItem.getUrl().getClearRegex();

        Function<WebElement, String> getChapUrl = new GetTargetValue(urlValue,urlClearRegex);

        TurnPage turnPage = new TurnPage(autoDirectory.getNext());
        int id = 0;//章节id,从0开始
        for (;;){
            WebElement directoryElement = edgeDriver.findElement(By.xpath(directoryXpath));
            List<WebElement> itemElement = directoryElement.findElements(By.xpath(itemXpath));
            for (WebElement i: itemElement){
                WebElement chapElement = i.findElement(By.xpath(chapXpath));
                String chapName = getChapName.apply(chapElement);
                WebElement urlElement = i.findElement(By.xpath(urlXpath));
                String chapUrl = getChapUrl.apply(urlElement);
                chapterList.add(new Chapter(id++,chapName, chapUrl));
            }
            if (!turnPage.execute(edgeDriver)) {
                //如果翻页失败，就跳出循环
                break;
            }
        }
        edgeDriver.quit();
        return bookDirectory ;
    }
}
